<template>
    <div class="vab-tabs">
        <el-tabs v-model="tabActive" :class="{['vab-tabs-content-' + theme.tabsBarStyle]: true,}"
                 class="vab-tabs-content"
                 type="card"
                 @tab-click="handleTabClick"
                 @tab-remove="handleTabRemove">
            <el-tab-pane
                v-for="item in visitedRoutes"
                :key="item.path"
                :closable="isNoClosable(item)"
                :name="item.path">
                <span slot="label" style="display: inline-block" @contextmenu.prevent="openMenu($event, item)">
<!--                  <template v-if="theme.showTabsBarIcon">-->
                    <!--                    &lt;!&ndash;<vab-icon-->
                    <!--                        v-if="item.meta && item.meta.icon"-->
                    <!--                        :icon="item.meta.icon"-->
                    <!--                        :is-custom-svg="item.meta.isCustomSvg"/>&ndash;&gt;-->
                    <!--                      &lt;!&ndash;  如果没有图标那么取第二级的图标 &ndash;&gt;-->
                    <!--                      &lt;!&ndash;<vab-icon v-else :icon="item.parentIcon"/>&ndash;&gt;-->
                    <!--                  </template>-->
                  <span>{{ translate(item.meta.nameI18nKey || item.meta.title) }}</span>
                </span>
            </el-tab-pane>
        </el-tabs>
    
    </div>
</template>

<script lang="ts">
import {handleActivePath} from '@/utils/routes'
import BaseVue from "@/common/base-vue";
import {Component, Prop, Watch} from 'vue-property-decorator';
import {RouterGetterEnum, SettingsGetterEnum, TabsActionsEnum, TabsGetterEnum} from '@/store/enum/store.enum'

@Component({components: {}})
export default class VabTabs extends BaseVue {
    @Prop({type: String, default: '',})
    private layout;
    
    private tabActive: string = '';
    private active: boolean = false;
    private visible: boolean = false;
    private top: number = 0;
    private left: number = 0;
    private hoverRoute: object = null;
    
    get visitedRoutes() {
        return this.$store.getters[TabsGetterEnum.visitedRoutes]
    };
    
    get routes() {
        return this.$store.getters[RouterGetterEnum.routes]
    };
    
    get theme() {
        return this.$store.getters[SettingsGetterEnum.theme]
    };
    
    @Watch('$route', {immediate: true})
    handler(route) {
        this.$nextTick(() => {
            this.addTabs(route)
        })
    };
    
    @Watch('visible', {})
    visibleChecked(value) {
        if (value) {
            document.body.addEventListener('click', this.closeMenu)
        } else {
            document.body.removeEventListener('click', this.closeMenu)
        }
    };
    
    created() {
        this.initNoClosableTabs(this.routes)
    };
    
    private addVisitedRoute(val: object) {
        this.$store.commit(TabsActionsEnum.addVisitedRoute, val)
    };
    
    private delVisitedRoute(val: string) {
        this.$store.commit(TabsActionsEnum.delVisitedRoute, val)
    };
    
    private delOthersVisitedRoutes(val: string) {
        this.$store.commit(TabsActionsEnum.delOthersVisitedRoutes, val)
    };
    
    private delLeftVisitedRoutes(val: string) {
        this.$store.commit(TabsActionsEnum.delLeftVisitedRoutes, val)
    };
    
    private delRightVisitedRoutes(val: string) {
        this.$store.commit(TabsActionsEnum.delRightVisitedRoutes, val)
    };
    
    private delAllVisitedRoutes() {
        this.$store.commit(TabsActionsEnum.delAllVisitedRoutes)
    };
    
    private handleTabClick(tab: object) {
        if (!this.isActive(tab.name))
            this.$router.push(this.visitedRoutes[tab.index])
    };
    
    private handleVisibleChange(val: boolean) {
        this.active = val
    };
    
    private initNoClosableTabs(routes) {
        routes.forEach((route) => {
            if (route.meta && route.meta.noClosable) this.addTabs(route, true)
            if (route.children) this.initNoClosableTabs(route.children)
        })
    };
    
    /**
     * 添加标签页
     * @param tag route
     * @param init 是否是从router获取路由
     * @returns {Promise<void>}
     */
    private async addTabs(tag, init = false) {
        let parentIcon: string = ''
        if (tag.matched && tag.matched.length > 1)
            parentIcon = tag.matched[1].meta.icon
        if (tag.name && tag.meta && tag.meta.tabHidden !== true) {
            const path = handleActivePath(tag, true)
            await this.addVisitedRoute({
                path: path,
                query: tag.query,
                params: tag.params,
                name: tag.name,
                matched: init ? [tag.name] : tag.matched.map((item) => item.name),
                parentIcon,
                meta: {...tag.meta},
            })
            this.tabActive = path
        }
    };
    
    /**
     * 根据原生路径删除标签中的标签
     * @param rawPath 原生路径
     * @returns {Promise<void>}
     */
    private async handleTabRemove(rawPath) {
        await this.delVisitedRoute(rawPath)
        if (this.isActive(rawPath)) {
            this.toLastTab()
        }
    };
    
    private handleCommand(command: string) {
        switch (command) {
            case 'closeOthersTabs':
                this.closeOthersTabs()
                break
            case 'closeLeftTabs':
                this.closeLeftTabs()
                break
            case 'closeRightTabs':
                this.closeRightTabs()
                break
            case 'closeAllTabs':
                this.closeAllTabs()
                break
        }
    };
    
    /**
     * 删除其他标签页
     * @returns {Promise<void>}
     */
    private async closeOthersTabs() {
        if (this.hoverRoute) {
            await this.$router.push(this.hoverRoute)
            await this.delOthersVisitedRoutes(this.hoverRoute.path)
        } else {
            await this.delOthersVisitedRoutes(handleActivePath(this.$route, true))
        }
        await this.closeMenu()
    };
    
    /**
     * 删除左侧标签页
     * @returns {Promise<void>}
     */
    private async closeLeftTabs() {
        if (this.hoverRoute) {
            await this.$router.push(this.hoverRoute)
            await this.delLeftVisitedRoutes(this.hoverRoute.path)
        } else {
            await this.delLeftVisitedRoutes(handleActivePath(this.$route, true))
        }
        await this.closeMenu()
    };
    
    /**
     * 删除右侧标签页
     * @returns {Promise<void>}
     */
    private async closeRightTabs() {
        if (this.hoverRoute) {
            await this.$router.push(this.hoverRoute)
            await this.delRightVisitedRoutes(this.hoverRoute.path)
        } else {
            await this.delRightVisitedRoutes(handleActivePath(this.$route, true))
        }
        await this.closeMenu()
    };
    
    /**
     * 删除所有标签页
     * @returns {Promise<void>}
     */
    private async closeAllTabs() {
        await this.delAllVisitedRoutes()
        this.toLastTab()
        await this.closeMenu()
    };
    
    /**
     * 跳转最后一个标签页
     */
    private toLastTab() {
        const latestView = this.visitedRoutes.slice(-1)[0];
        if (latestView) {
            this.$router.push(latestView);
        } else {
            this.$router.push('/');
        }
    };
    
    private isActive(path: string): boolean {
        return path === handleActivePath(this.$route, true);
    };
    
    private isNoClosable(tag): boolean {
        return this.visitedRoutes.length > 1;
    };
    
    private openMenu(e, item) {
        const offsetLeft = this.$el.getBoundingClientRect().left
        const offsetWidth = this.$el.offsetWidth
        const maxLeft = Math.round(offsetWidth)
        const left = Math.round(e.clientX - offsetLeft)
        if (left > maxLeft) {
            this.left = maxLeft;
        } else {
            this.left = left;
        }
        this.top = Math.round(e.clientY - 80);
        this.hoverRoute = item;
        this.hoverRoute.fullPath = item.path;
        this.visible = true;
    };
    
    private closeMenu() {
        this.visible = false;
        this.hoverRoute = null;
    };
}
</script>

<style lang="scss" scoped>
.vab-tabs {
    position: relative;
    box-sizing: border-box;
    display: flex;
    align-content: center;
    align-items: center;
    justify-content: space-between;
    min-height: $base-tabs-height;
    padding: 0 20px 1px 20px;
    user-select: none;
    border-top: 1px solid #f6f6f6;
    
    ::v-deep {
        .fold-unfold {
            margin-right: $base-margin;
        }
        
        [class*='ri'] {
            margin-right: 3px;
        }
    }
    
    &-content {
        width: calc(100% - 40px);
        
        &-card {
            height: $base-tag-item-height;
            
            ::v-deep {
                .el-tabs__nav-next,
                .el-tabs__nav-prev {
                    height: $base-tag-item-height;
                    line-height: $base-tag-item-height;
                }
                
                .el-tabs__header {
                    border-bottom: 0;
                    
                    
                    .el-tabs__nav {
                        border: 0;
                    }
                    
                    .el-tabs__item {
                        box-sizing: border-box;
                        height: $base-tag-item-height;
                        margin-right: 5px;
                        line-height: $base-tag-item-height;
                        border: 1px solid $base-border-color;
                        border-radius: $base-border-radius;
                        transition: padding 0.3s cubic-bezier(0.645, 0.045, 0.355, 1) !important;
                        
                        &.is-active {
                            color: $base-color-blue;
                            background: mix($base-color-white, $base-color-blue, 90%);
                            border: 1px solid $base-color-blue;
                            outline: none;
                        }
                        
                        &:hover {
                            border: 1px solid $base-color-blue;
                        }
                    }
                }
            }
        }
        
        &-smart {
            height: $base-tag-item-height;
            
            ::v-deep {
                .el-tabs__nav-next,
                .el-tabs__nav-prev {
                    height: $base-tag-item-height;
                    line-height: $base-tag-item-height;
                }
                
                .el-tabs__header {
                    border-bottom: 0;
                    
                    .el-tabs__nav {
                        border: 0;
                    }
                    
                    .el-tabs__item {
                        height: $base-tag-item-height;
                        margin-right: 5px;
                        line-height: $base-tag-item-height;
                        border: 0;
                        outline: none;
                        transition: padding 0.3s cubic-bezier(0.645, 0.045, 0.355, 1) !important;
                        
                        &.is-active {
                            background: mix($base-color-white, $base-color-blue, 90%);
                            outline: none;
                            
                            &:after {
                                width: 100%;
                                transition: $base-transition;
                            }
                        }
                        
                        &:after {
                            position: absolute;
                            bottom: 0;
                            left: 0;
                            width: 0;
                            height: 2px;
                            content: '';
                            background-color: $base-color-blue;
                            transition: $base-transition;
                        }
                        
                        &:hover {
                            background: mix($base-color-white, $base-color-blue, 90%);
                            
                            &:after {
                                width: 100%;
                                transition: $base-transition;
                            }
                        }
                    }
                }
            }
        }
        
        &-smooth {
            height: $base-tag-item-height + 4;
            
            ::v-deep {
                .el-tabs__nav-next,
                .el-tabs__nav-prev {
                    height: $base-tag-item-height + 4;
                    line-height: $base-tag-item-height + 4;
                }
                
                .el-tabs__header {
                    border-bottom: 0;
                    
                    .el-tabs__nav-wrap.is-scrollable {
                        padding-right: 40px;
                    }
                    
                    .el-tabs__nav {
                        border: 0;
                    }
                    
                    .el-tabs__nav-next, .el-tabs__nav-prev {
                        top: 10px;
                    }
                    
                    .el-tabs__item {
                        height: $base-tag-item-height + 4;
                        padding: 0 30px !important;
                        margin-top: ($base-tabs-height - $base-tag-item-height - 4)/2;
                        line-height: $base-tag-item-height + 4;
                        margin-right: 5px;
                        text-align: center;
                        border: 0;
                        outline: none;
                        transition: padding 0.3s cubic-bezier(0.645, 0.045, 0.355, 1) !important;
                        border-radius: 6px 6px 0 0;
                        background-color: $base-color-label-bgc;
                        color: $base-font-color-secondary;
                        user-select: none;
                        font-size: 16px;
                        font-weight: 400;
                        
                        .el-icon-close {
                            width: 0;
                            visibility: hidden;
                            line-height: 14px;
                        }
                        
                        span {
                            transform: translateX(3px);
                        }
                        
                        &:hover span:first-child, &:hover .el-icon-close {
                            transform: translateX(-6px);
                        }
                        
                        &.is-active span:first-child, &.is-active .el-icon-close {
                            transform: none;
                        }
                        
                        &.is-active {
                            padding: 0 30px;
                            color: $base-color-orange;
                            outline: none;
                            background-color: $base-color-white;
                            
                            .el-icon-close {
                                background-color: $base-color-orange;
                                color: #fff;
                            }
                            
                            &:hover {
                                padding: 0 30px !important;
                                color: $base-color-orange;
                            }
                            
                            .el-icon-close {
                                visibility: unset;
                            }
                        }
                        
                        &:hover {
                            padding: 0 16px 0 30px !important;
                            background: $base-color-white;
                            
                            .el-icon-close {
                                visibility: unset;
                            }
                        }
                    }
                }
            }
        }
    }
    
    .contextmenu {
        position: absolute;
        top: 0;
        left: 0;
        z-index: 10;
    }
    
    &-more {
        position: relative;
        
        &-active,
        &:hover {
            &:after {
                position: absolute;
                bottom: -1px;
                left: 0;
                height: 0;
                content: '';
            }
            
            .vab-tabs-more-icon {
                transform: rotate(90deg);
                
                .box-t {
                    &:before {
                        transform: rotate(45deg);
                    }
                }
                
                .box:before,
                .box:after {
                    background: $base-color-blue;
                }
            }
        }
        
        &-icon {
            display: inline-block;
            color: #9a9a9a;
            cursor: pointer;
            transition: transform 0.3s ease-out;
            
            .box {
                position: relative;
                display: block;
                width: 14px;
                height: 8px;
                
                &:before {
                    position: absolute;
                    top: 0;
                    left: 0;
                    width: 6px;
                    height: 6px;
                    content: '';
                    background: #9a9a9a;
                }
                
                &:after {
                    position: absolute;
                    top: 0;
                    left: 8px;
                    width: 6px;
                    height: 6px;
                    content: '';
                    background: #9a9a9a;
                }
            }
            
            .box-t {
                &:before {
                    transition: transform 0.3s ease-out 0.3s;
                }
            }
        }
    }
}
</style>
